/**
 * @作者 faner
 * @创建时间 2021/2/22 15:45
 */
package com.faner.fast.security.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.faner.fast.util.EncryptUtil;
import com.faner.fast.util.FastUtil;
import com.faner.fast.util.RedisUtil;
import com.faner.fast.util.ValueUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class FastOnlineUserService {

    private final RedisUtil redisUtil;

    /**
     * 保存在线用户信息
     * @param fastUser /
     * @param token /
     * @param request /
     */
    public void save(FastUser fastUser, String token, HttpServletRequest request) {
        String ip = ServletUtil.getClientIP(request);
        String browser = FastUtil.getBrowser(request);
        String address = FastUtil.getCityInfo(ip);
        FastOnlineUser onlineUser = null;
        try {
            onlineUser = new FastOnlineUser(fastUser.getUsername(), browser, ip, address, EncryptUtil.desEncrypt(token), LocalDateTime.now());
        } catch (Exception e) {
            e.printStackTrace();
        }
        redisUtil.set(ValueUtil.onlineKey + ":" + token, onlineUser, ValueUtil.expiration);
    }

    /**
     * 踢出用户
     * @param key /
     * @throws Exception /
     */
    public void kickOut(String key) throws Exception {
        key = ValueUtil.onlineKey +":"+ EncryptUtil.desDecrypt(key);
        redisUtil.del(key);
    }

    /**
     * 查询用户
     * @param key /
     * @return /
     */
    public FastOnlineUser getOne(String key) {
        key = ValueUtil.onlineKey +":"+ key;
        return (FastOnlineUser) redisUtil.get(key);
    }

    /**
     * 退出登录
     * @param token /
     */
    public void logout(String token) {
        String key = ValueUtil.onlineKey + token;
        redisUtil.del(key);
    }

    /**
     * 查询全部数据，不分页
     * @param filter /
     * @return /
     */
    public List<FastOnlineUser> getAll(String filter) {
        List<String> keys = redisUtil.scan(ValueUtil.onlineKey + "*");
        Collections.reverse(keys);
        List<FastOnlineUser> onlineUsers = new ArrayList<>();
        for (String key : keys) {
            FastOnlineUser onlineUser = (FastOnlineUser) redisUtil.get(key);
            if (StrUtil.isNotBlank(filter)) {
                if (onlineUser.toString().contains(filter)) {
                    onlineUsers.add(onlineUser);
                }
            } else {
                onlineUsers.add(onlineUser);
            }
        }
        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
        return onlineUsers;
    }

    /**
     * 检测用户是否在之前已经登录，已经登录踢下线
     * @param userName 用户名
     */
    public void checkLoginOnUser(String userName, String igoreToken) {
        List<FastOnlineUser> onlineUsers = getAll(userName);
        if (onlineUsers == null || onlineUsers.isEmpty()) {
            return;
        }
        for (FastOnlineUser onlineUser : onlineUsers) {
            if (onlineUser.getUserName().equals(userName)) {
                try {
                    String token = EncryptUtil.desDecrypt(onlineUser.getKey());
                    if (StrUtil.isNotBlank(igoreToken) && !igoreToken.equals(token)) {
                        this.kickOut(onlineUser.getKey());
                    } else if (StrUtil.isBlank(igoreToken)) {
                        this.kickOut(onlineUser.getKey());
                    }
                } catch (Exception e) {
                    log.error("checkUser is error", e);
                }
            }
        }
    }
}
